home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / oleo-1_4.lha / oleo-1.4 / io-utils.c < prev    next >
C/C++ Source or Header  |  1993-05-21  |  24KB  |  1,329 lines

  1. /*    Copyright (C) 1990, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This file is part of Oleo, the GNU Spreadsheet.
  4.  
  5. Oleo is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.
  9.  
  10. Oleo is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License along with
  16. Oleo; see the file COPYING.  If not, write to the Free Software Foundation, 675
  17. Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include "sysdef.h"
  22. #include "io-utils.h"
  23. #include "cell.h"
  24. #include "ref.h"
  25. #include "decompile.h"
  26. #include "io-generic.h"
  27. #include "io-abstract.h"
  28. #include "lists.h"
  29. #include "io-term.h"
  30. #include "cmd.h"
  31.  
  32.  
  33. /* Routines for formatting cell values */
  34. #ifdef __STDC__
  35. struct user_fmt;
  36. static char *pr_flt (double, struct user_fmt *, int);
  37. static char *pr_int (long, struct user_fmt *, int);
  38. #else
  39. static char *pr_flt ();
  40. static char *pr_int ();
  41. #endif
  42.  
  43.  
  44. /* Constants */
  45. char *bname[] =
  46. {
  47.   "#FALSE", "#TRUE"
  48. };
  49.  
  50. char numb_oflo[] = "########################################";
  51.  
  52. double __plinf;
  53. double __neinf;
  54. double __nan;
  55.  
  56. char nname[] = "#NOT_A_NUMBER";
  57. char iname[] = "#INFINITY";
  58. char mname[] = "#MINUS_INFINITY";
  59.  
  60. static double
  61. divide (a, b)
  62.      double a;
  63.      double b;
  64. {
  65.   return a / b;
  66. }
  67.  
  68. static RETSIGTYPE
  69. ignore_sig (sig)
  70.      int sig;
  71. {
  72.   (void)signal (SIGFPE, ignore_sig);
  73. }
  74.  
  75. /* It's ok of this fails and generates signals.  In that case, 
  76.  * the same signal will occur when evaluating formulas and a
  77.  * (less informative) error value substituted.  Note that this 
  78.  * should be called before init_eval.
  79.  */
  80. #ifdef __STDC__
  81. void
  82. init_infinity (void)
  83. #else
  84. void
  85. init_infinity ()
  86. #endif
  87. {
  88.   (void)signal (SIGFPE, ignore_sig);
  89.   __plinf = divide (1., 0.);
  90.   (void)signal (SIGFPE, ignore_sig);
  91.   __neinf = divide (-1., 0.);
  92.   (void)signal (SIGFPE, ignore_sig);
  93.   __nan = __plinf + __neinf;
  94. }
  95.  
  96.  
  97.  
  98. /* Slightly larger than the maximum exponent we ever expect to see */
  99. #define BIGFLT 309
  100. #ifdef TEST
  101. char print_buf[1024 * 8];
  102. #else
  103. char print_buf[BIGFLT + 20];
  104. #endif
  105.  
  106.  
  107.  
  108. /* Structures/vars/functions for dealing with formatting floating-point
  109.    numbers, etc */
  110.  
  111. struct user_fmt
  112.   {
  113.     char *p_hdr, *n_hdr;
  114.     char *p_trl, *n_trl;
  115.     char *zero, *comma, *decpt;
  116.     unsigned char prec;
  117.     double scale;
  118.   };
  119.  
  120.  
  121. struct user_fmt dol =
  122. {
  123.   "$", "($", 0, ")", "$0", ",", ".", PRC_FLT, 1};
  124.  
  125. struct user_fmt cma =
  126. {
  127.   0, "(", 0, ")", "0", ",", ".", PRC_FLT, 1};
  128.  
  129. struct user_fmt pct =
  130. {
  131.   0, "-", "%", "%", "0%", 0, ".", PRC_FLT, 100};
  132.  
  133. struct user_fmt fxt =
  134. {
  135.   0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1};
  136.  
  137. /* Variables */
  138.  
  139. struct user_fmt u[16] =
  140. {
  141.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  142.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  143.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  144.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  145.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  146.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  147.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  148.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  149.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  150.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  151.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  152.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  153.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  154.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  155.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  156.   {0, "-", 0, 0, "0", 0, ".", PRC_FLT, 1},
  157. };
  158.  
  159.  
  160. /* Turn a floating-point number into the canonical text form.  This scribbles
  161.    on print_buf */
  162.  
  163. #ifdef __STDC__
  164. char *
  165. flt_to_str (double val)
  166. #else
  167. char *
  168. flt_to_str (val)
  169.      double val;
  170. #endif
  171. {
  172.   double f;
  173.  
  174.   if (val == __plinf)
  175.     return iname;
  176.   if (val == __neinf)
  177.     return mname;
  178.   f = fabs (val);
  179.   if (f >= 1e6 || (f > 0 && f <= 9.9999e-6))
  180.     {
  181.       sprintf (print_buf, "%e", val);
  182.       return print_buf;
  183.     }
  184.   return pr_flt (val, &fxt, PRC_FLT);
  185. }
  186.  
  187.  
  188. #ifdef __STDC__
  189. char *
  190. long_to_str (long val)
  191. #else
  192. char *
  193. long_to_str (val)
  194.      long val;
  195. #endif
  196. {
  197.   sprintf (print_buf, "%ld", val);
  198.   return print_buf;
  199. }
  200.  
  201. /* create the human-readable version of the contents of a cell
  202.    This scribbles on print-buf bigtime */
  203.  
  204. #ifdef __STDC__
  205. char *
  206. print_cell (CELL *cp)
  207. #else
  208. char *
  209. print_cell (cp)
  210.      CELL *cp;
  211. #endif
  212. {
  213.   int j;
  214.   int p;
  215.   long num;
  216.   static char zeroes[] = "000000000000000";
  217.  
  218.   if (!cp)
  219.     return "";
  220.  
  221.   j = GET_FMT (cp);
  222.  
  223.   if (j == FMT_DEF)
  224.     j = default_fmt;
  225.   if (j == FMT_HID || GET_TYP (cp) == 0)
  226.     return "";
  227.  
  228.   if (GET_TYP (cp) == TYP_STR)
  229.     return cp->cell_str;
  230.   if (GET_TYP (cp) == TYP_BOL)
  231.     {
  232. #ifdef TEST
  233.       if (cp->cell_bol < 0 || cp->cell_bol > 1)
  234.     panic ("Bool %d out of range", cp->cell_bol);
  235. #endif
  236.       return bname[cp->cell_bol];
  237.     }
  238.   if (GET_TYP (cp) == TYP_ERR)
  239.     {
  240. #ifdef TEST
  241.       if (cp->cell_err > ERR_MAX || cp->cell_err < 0)
  242.     panic ("Error %d out of range", cp->cell_err);
  243. #endif
  244.       return ename[cp->cell_err];
  245.     }
  246.   if (GET_TYP (cp) == TYP_FLT)
  247.     {
  248.       p = GET_PRC (j);
  249.       switch (j | PRC_FLT)
  250.     {
  251.     case FMT_GPH:
  252.       if (cp->cell_flt < 0)
  253.         {
  254.           j = '-';
  255.           num = -(cp->cell_flt);
  256.         }
  257.       else if (cp->cell_flt >= 1)
  258.         {
  259.           j = '+';
  260.           num = (cp->cell_flt);
  261.         }
  262.       else
  263.         {
  264.           j = '0';
  265.           num = 1;
  266.         }
  267.     graph:
  268.       if (num >= sizeof (print_buf))
  269.         {
  270.           io_error_msg ("Cannot graph %d '%c'", p, j);
  271.           num = sizeof (print_buf) - 1;
  272.         }
  273.       print_buf[num] = '\0';
  274.       while (--num >= 0)
  275.         print_buf[num] = j;
  276.       return print_buf;
  277.  
  278.     case FMT_USR:
  279.       return pr_flt (cp->cell_flt, &u[p], u[p].prec);
  280.  
  281.     case FMT_GEN:
  282.       {
  283.         double f;
  284.  
  285.         f = fabs (cp->cell_flt);
  286.         if (f >= 1e6 || (f > 0 && f <= 9.9999e-6))
  287.           goto handle_exp;
  288.         return pr_flt (cp->cell_flt, &fxt, p);
  289.       }
  290.  
  291.     case FMT_DOL:
  292.       return pr_flt (cp->cell_flt, &dol, p);
  293.  
  294.     case FMT_CMA:
  295.       return pr_flt (cp->cell_flt, &cma, p);
  296.  
  297.     case FMT_PCT:
  298.       return pr_flt (cp->cell_flt, &pct, p);
  299.  
  300.     case FMT_FXT:
  301.       return pr_flt (cp->cell_flt, &fxt, p);
  302.  
  303.     case FMT_EXP:
  304.     handle_exp:
  305.       if (cp->cell_flt == __plinf)
  306.         return iname;
  307.       if (cp->cell_flt == __neinf)
  308.         return mname;
  309.       if (p == PRC_FLT)
  310.         sprintf (print_buf, "%e", cp->cell_flt);
  311.       else
  312.         sprintf (print_buf, "%.*e", p, cp->cell_flt);
  313.       return print_buf;
  314. #ifdef TEST
  315.     default:
  316.       panic ("Unknown format %d", j);
  317.       return 0;
  318. #endif
  319.     }
  320.     }
  321.  
  322.   if (GET_TYP (cp) == TYP_INT)
  323.     {
  324.       p = GET_PRC (j);
  325.       switch (j | PRC_FLT)
  326.     {
  327.     case FMT_GPH:
  328.       if (cp->cell_int < 0)
  329.         {
  330.           j = '-';
  331.           num = -(cp->cell_int);
  332.         }
  333.       else if (cp->cell_int >= 1)
  334.         {
  335.           j = '+';
  336.           num = (cp->cell_int);
  337.         }
  338.       else
  339.         {
  340.           j = '0';
  341.           num = 1;
  342.         }
  343.       goto graph;
  344.  
  345.     case FMT_USR:
  346.       return pr_int (cp->cell_int, &u[p], u[p].prec);
  347.  
  348.     case FMT_GEN:
  349.       sprintf (print_buf, "%ld", cp->cell_int);
  350.       return print_buf;
  351.  
  352.     case FMT_DOL:
  353.       return pr_int (cp->cell_int, &dol, p);
  354.  
  355.     case FMT_CMA:
  356.       return pr_int (cp->cell_int, &cma, p);
  357.  
  358.     case FMT_PCT:
  359.       return pr_int (cp->cell_int, &pct, p);
  360.  
  361.     case FMT_FXT:
  362.       if (p != PRC_FLT && p != 0)
  363.         sprintf (print_buf, "%ld.%.*s", cp->cell_int, p, zeroes);
  364.       else
  365.         sprintf (print_buf, "%ld", cp->cell_int);
  366.       return print_buf;
  367.  
  368.     case FMT_EXP:
  369.       if (p != PRC_FLT)
  370.         sprintf (print_buf, "%.*e", p, (double) (cp->cell_int));
  371.       else
  372.         sprintf (print_buf, "%e", (double) (cp->cell_int));
  373.       return print_buf;
  374. #ifdef TEST
  375.     default:
  376.       panic ("Unknown format %d", j);
  377.       return 0;
  378. #endif
  379.     }
  380.     }
  381. #ifdef TEST
  382.   panic ("Unknown cell type %d", GET_TYP (cp));
  383. #endif
  384.   return 0;
  385. }
  386.  
  387. /* Return the value of ROW,COL in a human-readable fashion
  388.    In paticular, strings have "" around them, and are \\ed
  389.  */
  390. #ifdef __STDC__
  391. char *
  392. cell_value_string (CELLREF row, CELLREF col)
  393. #else
  394. char *
  395. cell_value_string (row, col)
  396.      CELLREF row;
  397.      CELLREF col;
  398. #endif
  399. {
  400.   CELL *cp;
  401.  
  402.   cp = find_cell (row, col);
  403.   if (!cp || !GET_TYP (cp))
  404.     return "";
  405.   switch (GET_TYP (cp))
  406.     {
  407.     case TYP_FLT:
  408.       return flt_to_str (cp->cell_flt);
  409.  
  410.     case TYP_INT:
  411.       sprintf (print_buf, "%ld", cp->cell_int);
  412.       return print_buf;
  413.  
  414.     case TYP_STR:
  415.       return backslash_a_string (cp->cell_str, 1);
  416.  
  417.     case TYP_BOL:
  418.       return bname[cp->cell_bol];
  419.  
  420.     case TYP_ERR:
  421.       return ename[cp->cell_err];
  422. #ifdef TEST
  423.     default:
  424.       panic ("unknown type %d in cell_value_string", GET_TYP (cp));
  425. #endif
  426.     }
  427.   return 0;
  428. }
  429.  
  430. static char *
  431. pr_int (val, fmt, prec)
  432.      long val;
  433.      struct user_fmt *fmt;
  434.      int prec;
  435. {
  436.   char *pf, *pff, *pt;
  437.   long int n;
  438.   int nn = 0;
  439.  
  440.   pt = &print_buf[sizeof (print_buf) - 1];
  441.   *pt = '\0';
  442.  
  443.   n = fmt->scale * ((val < 0) ? -val : val);
  444.   if (n == 0)
  445.     return fmt->zero ? fmt->zero : "";
  446.  
  447.   pf = pff = (val < 0) ? fmt->n_trl : fmt->p_trl;
  448.   if (pf && *pf)
  449.     {
  450.       while (*pf)
  451.     pf++;
  452.       do
  453.     *--pt = *--pf;
  454.       while (pf != pff);
  455.     }
  456.  
  457.   if (prec != PRC_FLT && prec != 0)
  458.     {
  459.       while (prec-- > 0)
  460.     *--pt = '0';
  461.       pf = pff = fmt->decpt;
  462.       if (pf)
  463.     {
  464.       while (*pf)
  465.         pf++;
  466.       do
  467.         *--pt = *--pf;
  468.       while (pf != pff);
  469.     }
  470.       /* *--pt='.'; */
  471.     }
  472.   do
  473.     {
  474.       *--pt = (n % 10) + '0';
  475.       n /= 10;
  476.       if (nn++ == 2 && n > 0)
  477.     {
  478.       if (fmt->comma && *(fmt->comma))
  479.         {
  480.           for (pf = pff = fmt->comma; *pf; pf++)
  481.         ;
  482.           do
  483.         *--pt = *--pf;
  484.           while (pf != pff);
  485.         }
  486.       nn = 0;
  487.     }
  488.     }
  489.   while (n > 0);
  490.  
  491.   pf = pff = (val < 0) ? fmt->n_hdr : fmt->p_hdr;
  492.   if (pf && *pf)
  493.     {
  494.       while (*pf)
  495.     pf++;
  496.       do
  497.     *--pt = *--pf;
  498.       while (pf != pff);
  499.     }
  500.   return pt;
  501. }
  502.  
  503. static char *
  504. pr_flt (val, fmt, prec)
  505.      double val;
  506.      struct user_fmt *fmt;
  507.      int prec;
  508. {
  509.   char *iptr;
  510.   char *fptr;
  511.   char *pptr;
  512.   char *pf, *pff;
  513.   double fract, integer, tmpval;
  514.   int n;
  515.   int isneg;
  516.   int comlen;
  517.  
  518.   val *= fmt->scale;
  519.  
  520.   if (val == __plinf)
  521.     return iname;
  522.   if (val == __neinf)
  523.     return mname;
  524.   if (val != val)
  525.     return nname;
  526.  
  527.   iptr = &print_buf[BIGFLT];
  528.   fptr = &print_buf[BIGFLT];
  529.  
  530.  
  531.   if (val == 0)
  532.     return fmt->zero ? fmt->zero : "";
  533.  
  534.   if (val < 0)
  535.     {
  536.       isneg = 1;
  537.       val = -val;
  538.     }
  539.   else
  540.     isneg = 0;
  541.  
  542.   comlen = 0;
  543.   if (fmt->comma && *(fmt->comma))
  544.     for (pf = fmt->comma; *pf; comlen++, pf++)
  545.       ;
  546.  
  547.   fract = modf (val, &integer);
  548.   n = 0;
  549.   do
  550.     {
  551.       if (iptr < &print_buf[comlen])
  552.     return numb_oflo;
  553.       tmpval = modf (integer / 10, &integer);
  554.       *--iptr = '0' + (int) ((tmpval + .01) * 10);
  555.       if (comlen && n++ == 2 && integer)
  556.     {
  557.       n = 0;
  558.       pff = fmt->comma;
  559.       pf = pff + comlen;
  560.       do
  561.         *--iptr = *--pf;
  562.       while (pf != pff);
  563.     }
  564.     }
  565.   while (integer);
  566.  
  567.   if (prec)
  568.     {
  569.       int p1;
  570.  
  571.       p1 = (prec == PRC_FLT) ? 15 : (prec > 0) ? prec : -prec;
  572.       pf = fmt->decpt;
  573.       while (pf && *pf)
  574.     *fptr++ = *pf++;
  575.       /* *fptr++='.'; */
  576.       if (fract)
  577.     {
  578.       do
  579.         {
  580.           fract = modf (fract * 10, &tmpval);
  581.           *fptr++ = '0' + (int) tmpval;
  582.         }
  583.       while (--p1 && fract);
  584.     }
  585.       if (prec > 0 && prec != PRC_FLT)
  586.     while (p1--)
  587.       *fptr++ = '0';
  588.       else
  589.     {
  590.       fract = 0;
  591.       while (fptr[-1] == '0')
  592.         --fptr;
  593.       while (!isdigit (fptr[-1]))
  594.         --fptr;
  595.       *fptr = '\0';
  596.     }
  597.     }
  598.   if (fract)
  599.     {
  600.       (void) modf (fract * 10, &tmpval);
  601.       if (tmpval > 4)
  602.     {
  603.       iptr[-1] = '0';
  604.       for (pptr = fptr - 1;; --pptr)
  605.         {
  606.           if (!isdigit (*pptr))
  607.         continue;
  608.           else if (*pptr == '9')
  609.         {
  610.           if (pptr == fptr - 1 && pptr > &print_buf[BIGFLT] && (prec < 0 || prec == PRC_FLT))
  611.             {
  612.               --fptr;
  613.               while (!isdigit (pptr[-1]))
  614.             {
  615.               --fptr;
  616.               --pptr;
  617.             }
  618.               *pptr = '\0';
  619.             }
  620.           else
  621.             *pptr = '0';
  622.         }
  623.           else
  624.         {
  625.           (*pptr)++;
  626.           break;
  627.         }
  628.         }
  629.       if (pptr < iptr)
  630.         {
  631.           --iptr;
  632.           if (n == 3)
  633.         {
  634.           char tmpch;
  635.  
  636.           tmpch = *iptr++;
  637.           for (pf = pff = fmt->comma; *pf; pf++)
  638.             ;
  639.           do
  640.             *--iptr = *--pf;
  641.           while (pf != pff);
  642.           *--iptr = tmpch;
  643.         }
  644.         }
  645.     }
  646.     }
  647.   pf = pff = (isneg) ? fmt->n_hdr : fmt->p_hdr;
  648.   if (pf && *pf)
  649.     {
  650.       while (*pf)
  651.     pf++;
  652.       do
  653.     *--iptr = *--pf;
  654.       while (pf != pff);
  655.     }
  656.  
  657.   pf = (isneg) ? fmt->n_trl : fmt->p_trl;
  658.   while (pf && *pf)
  659.     *fptr++ = *pf++;
  660.   *fptr = 0;
  661.   return iptr;
  662. }
  663.  
  664. #ifdef __STDC__
  665. char *
  666. adjust_prc (char *oldp, CELL *cp, int width, int smallwid, int just)
  667. #else
  668. char *
  669. adjust_prc (oldp, cp, width, smallwid, just)
  670.      char *oldp;
  671.      CELL *cp;
  672.      int width;
  673.      int smallwid;
  674.      int just;
  675. #endif
  676. {
  677.   int fmt;
  678.   int prc;
  679.   struct user_fmt *ufmt;
  680.   char *bptr;
  681.   char *eptr;
  682.   int len;
  683.  
  684.   fmt = GET_FMT (cp);
  685.   if (fmt == FMT_DEF)
  686.     fmt = default_fmt;
  687.   prc = GET_PRC (fmt);
  688.   switch (fmt | PRC_FLT)
  689.     {
  690.     case FMT_GPH:
  691.     case FMT_HID:
  692.       return numb_oflo;
  693.     case FMT_DOL:
  694.       ufmt = &dol;
  695.       goto deal_fmt;
  696.  
  697.     case FMT_CMA:
  698.       ufmt = &cma;
  699.       goto deal_fmt;
  700.  
  701.     case FMT_PCT:
  702.       ufmt = &cma;
  703.       goto deal_fmt;
  704.  
  705.     case FMT_FXT:
  706.       ufmt = &fxt;
  707.       goto deal_fmt;
  708.  
  709.     case FMT_USR:
  710.       ufmt = &u[prc];
  711.       prc = ufmt->prec;
  712.       goto deal_fmt;
  713.  
  714.     case FMT_GEN:
  715.       if (prc != PRC_FLT)
  716.     return numb_oflo;
  717.       if (index (oldp, 'e') || !index (oldp, '.'))
  718.     goto handle_exp;
  719.  
  720.       ufmt = &fxt;
  721.       prc = PRC_FLT;
  722.       goto deal_fmt;
  723.  
  724.     deal_fmt:
  725.       if (prc != PRC_FLT)
  726.     return numb_oflo;
  727.       len = strlen (oldp);
  728.       bptr = (char *)strstr (oldp, ufmt->decpt);
  729.       if (!bptr)
  730.     return numb_oflo;
  731.       while (eptr = (char *)strstr (bptr + 1, ufmt->decpt))
  732.     bptr = eptr;
  733.  
  734.       if (width < bptr - oldp)
  735.     return numb_oflo;
  736.       if (bptr - oldp + strlen (ufmt->decpt) >= width)
  737.     prc = 0;
  738.       else
  739.     {
  740.       prc = width - (strlen (ufmt->decpt) + bptr - oldp);
  741.     }
  742.       bptr = pr_flt (cp->cell_flt, ufmt, -prc);
  743.       len = strlen (bptr);
  744.       if (len > width && prc > 0)
  745.     {
  746.       bptr = pr_flt (cp->cell_flt, ufmt, -(prc - 1));
  747.       len = strlen (bptr);
  748.     }
  749.       if (len > width)
  750.     return numb_oflo;
  751.       break;
  752.  
  753.     case FMT_EXP:
  754.     handle_exp:
  755.       {
  756.     double f;
  757.  
  758.     f = fabs (cp->cell_flt);
  759.     if (f > 9.99999e99 || f < 1e-99)
  760.       len = width - 7;
  761.     else            /* if(f>9.9999999e9 || f<1e-9) */
  762.       len = width - 6;
  763.     /* else
  764.                 len=width-5; */
  765.     if (cp->cell_flt < 0)
  766.       --len;
  767.     if (len > 0)
  768.       {
  769.         sprintf (oldp, "%.*e", len, cp->cell_flt);
  770.         len = strlen (oldp);
  771.         if (len <= width)
  772.           {
  773.         bptr = oldp;
  774.         break;
  775.           }
  776.       }
  777.       }
  778.       return numb_oflo;
  779.     default:
  780.       bptr = 0;
  781.       len = 0;
  782. #ifdef TEST
  783.       panic ("Unknown format %d in adjust_prc()", fmt);
  784. #endif
  785.       break;
  786.     }
  787.  
  788.   /* If we get here, bptr points to a a string of len characters
  789.        (len<=width) that we want to output */
  790.   if (len < smallwid)
  791.     {
  792.       if (just == JST_RGT || just == JST_CNT)
  793.     {
  794.       int n;
  795.  
  796.       n = (just == JST_RGT) ? smallwid - len : (1 + smallwid - len) / 2;
  797.       for (;;)
  798.         {
  799.           bptr[len + n] = bptr[len];
  800.           if (len-- == 0)
  801.         break;
  802.         }
  803.       while (n-- >= 0)
  804.         bptr[n] = ' ';
  805.     }
  806.     }
  807.   return bptr;
  808. }
  809.  
  810.  
  811. #ifdef __STDC__
  812. void
  813. set_usr_stats (int usr_n, char **usr_buf)
  814. #else
  815. void
  816. set_usr_stats (usr_n, usr_buf)
  817.      int usr_n;
  818.      char **usr_buf;
  819. #endif
  820. {
  821.   int len;
  822.   int i;
  823.   char *p_in, *p_out;
  824.  
  825.   len = 0;
  826.   for (i = 0; i < 7; i++)
  827.     len += strlen (usr_buf[i]);
  828.   u[usr_n].p_hdr = ck_malloc (len + 7);
  829.   p_out = u[usr_n].p_hdr;
  830.   if (usr_buf[0][0])
  831.     {
  832.       p_in = usr_buf[0];
  833.       while (*p_out++ = *p_in++)
  834.     ;
  835.     }
  836.   else
  837.     *p_out++ = '\0';
  838.  
  839.   if (usr_buf[1][0])
  840.     {
  841.       p_in = usr_buf[1];
  842.       u[usr_n].n_hdr = p_out;
  843.       while (*p_out++ = *p_in++)
  844.     ;
  845.     }
  846.   else
  847.     u[usr_n].n_hdr = 0;
  848.  
  849.   if (usr_buf[2][0])
  850.     {
  851.       p_in = usr_buf[2];
  852.       u[usr_n].p_trl = p_out;
  853.       while (*p_out++ = *p_in++)
  854.     ;
  855.     }
  856.   else
  857.     u[usr_n].p_trl = 0;
  858.  
  859.   if (usr_buf[3][0])
  860.     {
  861.       p_in = usr_buf[3];
  862.       u[usr_n].n_trl = p_out;
  863.       while (*p_out++ = *p_in++)
  864.     ;
  865.     }
  866.   else
  867.     u[usr_n].n_trl = 0;
  868.  
  869.   if (usr_buf[4][0])
  870.     {
  871.       p_in = usr_buf[4];
  872.       u[usr_n].zero = p_out;
  873.       while (*p_out++ = *p_in++)
  874.     ;
  875.     }
  876.   else
  877.     u[usr_n].zero = 0;
  878.  
  879.   if (usr_buf[5][0])
  880.     {
  881.       p_in = usr_buf[5];
  882.       u[usr_n].comma = p_out;
  883.       while (*p_out++ = *p_in++)
  884.     ;
  885.     }
  886.   else
  887.     u[usr_n].comma = 0;
  888.  
  889.   if (usr_buf[6][0])
  890.     {
  891.       p_in = usr_buf[6];
  892.       u[usr_n].decpt = p_out;
  893.       while (*p_out++ = *p_in++)
  894.     ;
  895.     }
  896.   else
  897.     u[usr_n].decpt = 0;
  898.  
  899.   if (!stricmp (usr_buf[7], "float") || !stricmp (usr_buf[7], "f"))
  900.     u[usr_n].prec = 15;
  901.   else
  902.     u[usr_n].prec = astol (&usr_buf[7]);
  903.  
  904.   u[usr_n].scale = astof (&usr_buf[8]);
  905. }
  906.  
  907. #ifdef __STDC__
  908. int
  909. usr_set_fmts (void)
  910. #else
  911. int
  912. usr_set_fmts ()
  913. #endif
  914. {
  915.   int n;
  916.   int ret = 0;
  917.  
  918.   for (n = 0; n < 16; n++)
  919.     if (u[n].p_hdr)
  920.       ret |= 1 << n;
  921.   return ret;
  922. }
  923.  
  924. #ifdef __STDC__
  925. void
  926. get_usr_stats (int usr_num, char **usr_buf)
  927. #else
  928. void
  929. get_usr_stats (usr_num, usr_buf)
  930.      int usr_num;
  931.      char **usr_buf;
  932. #endif
  933. {
  934.   static char buf1[30];
  935.   static char buf2[30];
  936.   static char NullStr[] = "";
  937.  
  938.   usr_buf[0] = u[usr_num].p_hdr ? u[usr_num].p_hdr : NullStr;
  939.   usr_buf[1] = u[usr_num].n_hdr ? u[usr_num].n_hdr : NullStr;
  940.   usr_buf[2] = u[usr_num].p_trl ? u[usr_num].p_trl : NullStr;
  941.   usr_buf[3] = u[usr_num].n_trl ? u[usr_num].n_trl : NullStr;
  942.   usr_buf[4] = u[usr_num].zero ? u[usr_num].zero : NullStr;
  943.   usr_buf[5] = u[usr_num].comma ? u[usr_num].comma : NullStr;
  944.   usr_buf[6] = u[usr_num].decpt ? u[usr_num].decpt : NullStr;
  945.   if (u[usr_num].prec == 15)
  946.     usr_buf[7] = "float";
  947.   else
  948.     {
  949.       sprintf (buf1, "%u", u[usr_num].prec);
  950.       usr_buf[7] = buf1;
  951.     }
  952.   sprintf (buf2, "%.12g", u[usr_num].scale);
  953.   usr_buf[8] = buf2;
  954. }
  955.  
  956. /* Functions for printing out the names of cells and ranges */
  957.  
  958. #ifdef __STDC__
  959. char *
  960. cell_name (CELLREF rr, CELLREF cc)
  961. #else
  962. char *
  963. cell_name (rr, cc)
  964.      CELLREF rr;
  965.      CELLREF cc;
  966. #endif
  967. {
  968.   static char strs[2][20];
  969.   static num = 0;
  970.   char *ptr;
  971.  
  972.   num = num ? 0 : 1;
  973.  
  974.   if (a0)
  975.     {
  976.       ptr = &strs[num][9];
  977.       sprintf (ptr, "%u", rr);
  978.       if (cc < MIN_COL + 26)
  979.     *--ptr = 'A' - MIN_COL + cc;
  980. #if MAX_COL>702
  981.       else if (cc < MIN_COL + 702)
  982.     {
  983.       cc -= MIN_COL + 26;
  984.       *--ptr = 'A' + cc % 26;
  985.       *--ptr = 'A' + cc / 26;
  986.     }
  987.       else if (cc < MIN_COL + 18278)
  988.     {
  989.       cc -= MIN_COL + 702;
  990.       *--ptr = 'A' + cc % 26;
  991.       cc /= 26;
  992.       *--ptr = 'A' + cc % 26;
  993.       *--ptr = 'A' + cc / 26;
  994.     }
  995.       else
  996.     {
  997.       cc -= MIN_COL + 18278;
  998.       *--ptr = 'A' + cc % 26;
  999.       cc /= 26;
  1000.       *--ptr = 'A' + cc % 26;
  1001.       cc /= 26;
  1002.       *--ptr = 'A' + cc % 26;
  1003.       *--ptr = 'A' + cc / 26;
  1004.     }
  1005. #else
  1006.       else
  1007.     {
  1008.       cc -= MIN_COL + 26;
  1009.       *--ptr = 'A' + cc % 26;
  1010.       *--ptr = 'A' + cc / 26;
  1011.     }
  1012. #endif
  1013.     }
  1014.   else
  1015.     {
  1016.       ptr = &strs[num][0];
  1017.       sprintf (ptr, "r%uc%u", rr, cc);
  1018.     }
  1019.   return ptr;
  1020. }
  1021.  
  1022. #ifdef __STDC__
  1023. char *
  1024. range_name (struct rng *rng)
  1025. #else
  1026. char *
  1027. range_name (rng)
  1028.      struct rng *rng;
  1029. #endif
  1030. {
  1031.   CELLREF lr, lc, hr, hc;
  1032.   static char buf[2][40];
  1033.   static num;
  1034.   char *ptr;
  1035.  
  1036.   ptr = &buf[num][0];
  1037.   num = num ? 0 : 1;
  1038.  
  1039.   lr = rng->lr;
  1040.   lc = rng->lc;
  1041.   hr = rng->hr;
  1042.   hc = rng->hc;
  1043.  
  1044.   if (a0)
  1045.     sprintf (ptr, "%s:%s", cell_name (lr, lc), cell_name (hr, hc));
  1046.   else
  1047.     {
  1048.       if (lr == hr && lc == hc)
  1049.     sprintf (ptr, "r%uc%u", lr, lc);
  1050.       else if (lr == hr && lc != hc)
  1051.     sprintf (ptr, "r%uc%u:%u", lr, lc, hc);
  1052.       else if (lr != hr && lc == hc)
  1053.     sprintf (ptr, "r%u:%uc%u", lr, hr, lc);
  1054.       else
  1055.     sprintf (ptr, "r%u:%uc%u:%u", lr, hr, lc, hc);
  1056.     }
  1057.   return ptr;
  1058. }
  1059.  
  1060.  
  1061. /* Parse a range, allowing variable names.
  1062.  * Return 1 on failure, 0 on succes.
  1063.  */
  1064. #ifdef __STDC__
  1065. int
  1066. get_abs_rng (char **pptr, struct rng *retp)
  1067. #else
  1068. int
  1069. get_abs_rng (pptr, retp)
  1070.      char **pptr;
  1071.      struct rng *retp;
  1072. #endif
  1073. {
  1074.   unsigned char n;
  1075.   struct rng ignored;
  1076.  
  1077.   if (!retp)
  1078.     retp = &ignored;
  1079.  
  1080.   while (**pptr == ' ')
  1081.     (*pptr)++;
  1082.   if (!**pptr)
  1083.     return 1;
  1084.   cur_row = curow;
  1085.   cur_col = cucol;
  1086.   n = parse_cell_or_range (pptr, retp);
  1087.   if (!n)
  1088.     {
  1089.       struct var *v;
  1090.       char *ptr;
  1091.  
  1092.       ptr = *pptr;
  1093.       while (ptr[n] && ptr[n] != ' ')
  1094.     n++;
  1095.       v = find_var (ptr, n);
  1096.       if (!v)
  1097.     return 1;
  1098.       (*pptr) += n;
  1099.       *retp = v->v_rng;
  1100.     }
  1101.   return 0;
  1102. }
  1103.  
  1104.  
  1105. #ifdef __STDC__
  1106. char *
  1107. col_to_str (CELLREF col)
  1108. #else
  1109. char *
  1110. col_to_str (col)
  1111.      CELLREF col;
  1112. #endif
  1113. {
  1114.   static char strs[2][10];
  1115.   static num;
  1116.   char *ptr;
  1117.  
  1118.   ptr = &strs[num][9];
  1119.   num = num ? 0 : 1;
  1120.  
  1121.   if (col < MIN_COL + 26)
  1122.     *--ptr = 'A' - MIN_COL + col;
  1123. #if MAX_COL>702
  1124.   else if (col < MIN_COL + 702)
  1125.     {
  1126.       col -= MIN_COL + 26;
  1127.       *--ptr = 'A' + col % 26;
  1128.       *--ptr = 'A' + col / 26;
  1129.     }
  1130.   else if (col < MIN_COL + 18278)
  1131.     {
  1132.       col -= MIN_COL + 702;
  1133.       *--ptr = 'A' + col % 26;
  1134.       col /= 26;
  1135.       *--ptr = 'A' + col % 26;
  1136.       *--ptr = 'A' + col / 26;
  1137.     }
  1138.   else
  1139.     {
  1140.       col -= MIN_COL + 18278;
  1141.       *--ptr = 'A' + col % 26;
  1142.       col /= 26;
  1143.       *--ptr = 'A' + col % 26;
  1144.       col /= 26;
  1145.       *--ptr = 'A' + col % 26;
  1146.       *--ptr = 'A' + col / 26;
  1147.     }
  1148. #else
  1149.   else
  1150.     {
  1151.       col -= MIN_COL + 26;
  1152.       *--ptr = 'A' + col % 26;
  1153.       *--ptr = 'A' + col / 26;
  1154.     }
  1155. #endif
  1156.   return ptr;
  1157. }
  1158.  
  1159. #ifdef __STDC__
  1160. void
  1161. clear_spreadsheet (void)
  1162. #else
  1163. void
  1164. clear_spreadsheet ()
  1165. #endif
  1166. {
  1167.   int n;
  1168.  
  1169.   flush_everything ();
  1170.   /* flush_widths(); */
  1171.   flush_all_timers ();
  1172.   for (n = 0; n < 16; n++)
  1173.     {
  1174.       if (u[n].p_hdr)
  1175.     {
  1176.       free (u[n].p_hdr);
  1177.       u[n].p_hdr = 0;
  1178.       u[n].prec = PRC_FLT;
  1179.       u[n].scale = 1;
  1180.     }
  1181.     }
  1182.   default_width = saved_default_width;
  1183.   default_height = saved_default_height;
  1184.   default_jst = JST_LFT;
  1185.   default_fmt = FMT_GEN;
  1186.   default_lock = LCK_UNL;
  1187. }
  1188.  
  1189. char *ename[] =
  1190. {
  1191.   "#WHAT?",
  1192.   "#ERROR", "#BAD_INPUT", "#NON_NUMBER", "#NON_STRING",
  1193.   "#NON_BOOL", "#NON_RANGE", "#OUT_OF_RANGE", "#NO_VALUES",
  1194.   "#DIV_BY_ZERO", "#BAD_NAME", "#NOT_AVAIL", "#PARSE_ERROR",
  1195.   "#NEED_OPEN", "#NEED_CLOSE", "#NEED_QUOTE", "#UNK_CHAR",
  1196.   "#UNK_FUNC",
  1197.   0
  1198. };
  1199.  
  1200. char tname[] = "#TRUE";
  1201. char fname[] = "#FALSE";
  1202.  
  1203.  
  1204. #ifdef __STDC__
  1205. int
  1206. words_imatch (char ** ptr, char * key)
  1207. #else
  1208. int
  1209. words_imatch (ptr, key)
  1210.      char ** ptr;
  1211.      char * key;
  1212. #endif
  1213. {
  1214.   char * str = * ptr;
  1215.  
  1216.   while (isspace (*str))
  1217.     ++str;
  1218.   while (isspace (*key))
  1219.     ++key;
  1220.  
  1221.   while (1)
  1222.     {
  1223.       while (*str && *key && (toupper (*str) == toupper (*key)))
  1224.     {
  1225.       ++str;
  1226.       ++key;
  1227.     }
  1228.       /* If we're not at word breaks in both strings... */
  1229.       if (!((!*str || isspace (*str)) && (!*key || isspace (*key))))
  1230.     return 0;
  1231.       else
  1232.     {
  1233.       while (isspace (*key))
  1234.         ++key;
  1235.       while (isspace (*str))
  1236.         ++str;
  1237.       if (!*key)
  1238.         {
  1239.           *ptr = str;
  1240.           return 1;
  1241.         }
  1242.     }
  1243.     }
  1244. }
  1245.  
  1246. #ifdef __STDC__
  1247. int
  1248. parray_len (char ** array)
  1249. #else
  1250. int
  1251. parray_len (array)
  1252.      char ** array;
  1253. #endif
  1254. {
  1255.   int x;
  1256.   for (x = 0; array[x]; ++x) ;
  1257.   return x;
  1258. }
  1259.  
  1260.  
  1261. /* Return the index of CHECK in KEYS or -1.  Case and whitespeace insenstive.
  1262.  */
  1263.  
  1264. #ifdef __STDC__
  1265. int
  1266. words_member (char ** keys, int len, char * check)
  1267. #else
  1268. int
  1269. words_member (keys, len, check)
  1270.      char ** keys;
  1271.      int len;
  1272.      char * check;
  1273. #endif
  1274. {
  1275.   int x;
  1276.   for (x = 0; x < len; ++x)
  1277.     {
  1278.       char * ch = check;
  1279.       if (words_imatch (&ch, keys[x]))
  1280.     if (!*ch)
  1281.       return x;
  1282.     }
  1283.   return -1;
  1284. }
  1285.  
  1286. #ifdef __STDC__
  1287. int
  1288. prompt_len (char * prompt)
  1289. #else
  1290. int
  1291. prompt_len (prompt)
  1292.      char * prompt;
  1293. #endif
  1294. {
  1295.   char * pos;
  1296.   if (!prompt)
  1297.     return 0;
  1298.   for (pos = prompt; *pos && (*pos != '\n'); ++pos)
  1299.     ;
  1300.   return pos - prompt;
  1301. }
  1302.  
  1303.  
  1304. #ifdef __STDC__
  1305. int
  1306. says_default (char * str)
  1307. #else
  1308. int
  1309. says_default (str)
  1310.      char * str;
  1311. #endif
  1312. {
  1313.   char * key = "ault";
  1314.   if (strincmp(str, "def", 3))
  1315.     return 0;
  1316.   str += 3;
  1317.   while (*str && *key)
  1318.     {
  1319.       int c = isupper (*str) ? tolower (*str) : *str;
  1320.       if (c != *key)
  1321.     return 0;
  1322.       ++key;
  1323.       ++str;
  1324.     }
  1325.   while (isspace(*str))
  1326.     ++str;
  1327.   return !*str;
  1328. }
  1329.